package org.orbis.memorycontroller.struct;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.Arrays;

public class FileBufferTuple{
	private String fileName;
	private File descriptor;
	private RandomAccessFile accessor;
	private FileChannel channel;
	private ByteBuffer buffer;

	private FileBufferTuple(){}

	public static FileBufferTuple create(String name, int fileSize){
		FileBufferTuple newTuple = new FileBufferTuple();
		newTuple.fileName = name;
		newTuple.descriptor = new File(name);
		if(newTuple.descriptor == null) return null;
		if(!newTuple.descriptor.exists()){
			try{
				newTuple.descriptor.createNewFile();
			}catch(IOException e){
				e.printStackTrace();
				return null;
			}
		}
		try{
			newTuple.accessor = new RandomAccessFile(newTuple.descriptor, "rw");
			newTuple.channel = newTuple.accessor.getChannel();
			newTuple.buffer = newTuple.channel.map(MapMode.READ_WRITE, 0, fileSize);
		}catch(IOException e){
			e.printStackTrace();
			return null;
		}

		return newTuple;
	}
	
	public void overwriteData(byte[] array) {
		if(array.length >= this.buffer.capacity())
			array = Arrays.copyOf(array, this.buffer.capacity());
		synchronized(this.buffer){
			this.buffer.position(0);
			this.buffer.put(array);
			this.buffer.position(0);
		}
	}
	
	@Override
	public void finalize() throws Throwable{
		this.channel.close();
		this.accessor.close();
		super.finalize();
	}

	public String fileName(){
		return fileName;
	}

	public File descriptor(){
		return descriptor;
	}
	
	public FileChannel channel() {
		return channel;
	}

	public ByteBuffer buffer(){
		return buffer;
	}
}
